//
//  RichTextMaker.m
//  YanXiuWang
//
//  Created by 慧趣小歪 on 16/12/10.
//  Copyright © 2016年 小分队. All rights reserved.
//

#import "RichTextMaker.h"


@interface RichTextMaker ()

@property (nonatomic) NSMutableAttributedString * mAttr;

@property (nonatomic) NSString * mText;                     //文字内容
@property (nonatomic) UIFont * mTextFont;                   //文字字体
@property (nonatomic) UIColor * mBackColor;                 //背景色
@property (nonatomic) UIColor * mTextColor;                 //文字颜色

@property (nonatomic) NSParagraphStyle * mParagraphStyle;   //段落样式

@property (nonatomic) UIColor * mTextUnderlineColor;        //下划线颜色
@property (nonatomic) NSUnderlineStyle mTextUnderlineStyle; //下划线样式

@property (nonatomic) UIColor * mTextStrikethroughColor;    //删除线颜色
@property (nonatomic) NSInteger mTextStrikethroughStyle;    //删除线样式

@property (nonatomic) UIColor * mTextStrokeColor;           //描边颜色
@property (nonatomic) CGFloat mTextStrokeWidth;             //描边宽

@property (nonatomic) NSInteger mTextLigature;
@property (nonatomic) CGFloat mTextKern;                    //文字横向间距
@property (nonatomic) CGFloat mTextExpansion;               //文字横向宽窄
@property (nonatomic) CGFloat mTextObliqueness;             //文字倾斜度
@property (nonatomic) NSShadow * mTextShadow;               //文字阴影
//@property (nonatomic) NSTextAttachment * mTextAttachment;   //附加元素
@property (nonatomic) NSString * mTextLink;                 //超链接(NSURL 或 NSString)
@property (nonatomic) CGFloat mTextBaselineOffset;          //文字对齐基线偏移
@property (nonatomic) NSWritingDirection mTextDirection;    //文字书写方向 // NSArray of NSNumbers representing the nested levels of writing direction overrides as defined by Unicode LRE, RLE, LRO, and RLO characters.  The control characters can be obtained by masking NSWritingDirection and NSWritingDirectionFormatType values.  LRE: NSWritingDirectionLeftToRight|NSWritingDirectionEmbedding, RLE: NSWritingDirectionRightToLeft|NSWritingDirectionEmbedding, LRO: NSWritingDirectionLeftToRight|NSWritingDirectionOverride, RLO: NSWritingDirectionRightToLeft|NSWritingDirectionOverride,
@property (nonatomic) NSInteger mTextVerticalGlyph;          //文字排版方向 An NSNumber containing an integer value.  0 means horizontal text.  1 indicates vertical text.  If not specified, it could follow higher-level vertical orientation settings.  Currently on iOS, it's always horizontal.  The behavior for any other value is undefined.

@property (nonatomic) NSString * mTextEffect;               // 文字凸起? NSTextEffectLetterpressStyle


@end

RichTextMaker * RichFormat(NSString * format, ...) {
    va_list args;
    va_start(args, format);
    NSString *result = [[NSString alloc] initWithFormat:format arguments:args];
    va_end(args);
    return RichText(result);
}

RichTextMaker * RichText(NSString* text) {
    return [RichTextMaker new].text(text);
}


@implementation RichTextMaker

- (void)resetAttributeds {
    _mTextFont = nil;
    _mTextShadow = nil;
    _mTextColor = nil;
    _mBackColor = nil;
    _mTextLigature = 1;
    _mTextKern = 0;
    _mTextExpansion = 0;
    _mTextObliqueness = 0;
    
    _mTextUnderlineStyle = NSUnderlineStyleNone;
    _mTextUnderlineColor = nil;
    
    _mTextStrikethroughStyle = 0;
    _mTextStrikethroughColor = nil;
    
    _mTextStrokeWidth = 0;
    _mTextStrokeColor = nil;
    
    //_mTextAttachment = nil;
    _mTextLink = nil;
    
    _mTextBaselineOffset = 0;
    
    _mTextDirection = NSWritingDirectionLeftToRight;
    
    _mTextEffect = nil;
    
    _mTextVerticalGlyph = 0;
    
    _mParagraphStyle = nil;
}

- (void)createAttributedString {
    if (_mText == nil) return;
    
    NSMutableDictionary<NSString *,id> *attributes = [NSMutableDictionary dictionary];
    
    attributes[NSFontAttributeName] = _mTextFont;
    attributes[NSShadowAttributeName] = _mTextShadow;
    attributes[NSForegroundColorAttributeName] = _mTextColor;
    attributes[NSBackgroundColorAttributeName] = _mBackColor;
    //attributes[NSAttachmentAttributeName] = _mTextAttachment;
    attributes[NSTextEffectAttributeName] = _mTextEffect;

    // 文字超链接
    if (_mTextLink != nil) {
        // 匹配如果是URL
        NSRegularExpression *regular = [NSRegularExpression regularExpressionWithPattern:@"[a-zA-Z0-9_]+://[\\s\\S]*" options:NSRegularExpressionCaseInsensitive error:nil];
        
        NSString * temp = [_mTextLink stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@" \n\t\r\n"]];
        
        if ([regular rangeOfFirstMatchInString:temp options:0 range:NSMakeRange(0, temp.length)].location != 0) {
            attributes[NSLinkAttributeName] = [NSURL URLWithString:temp];
        } else {
            attributes[NSLinkAttributeName] = _mTextLink;
        }
    }

    //////段落样式///////
    attributes[NSParagraphStyleAttributeName] = _mParagraphStyle;
    
    // 文字书写方向 左向右 或 右向左
    attributes[NSWritingDirectionAttributeName] = _mTextDirection == NSWritingDirectionLeftToRight ? nil : @(_mTextDirection);
    
    // 文字纵向排版 1纵向 0横向
    attributes[NSVerticalGlyphFormAttributeName] = _mTextVerticalGlyph == 0 ? nil : @1;
    
    // 文字对齐基线上下偏移
    attributes[NSBaselineOffsetAttributeName] = _mTextBaselineOffset == 0 ? nil : @(_mTextBaselineOffset);
    
    // 文字间距
    attributes[NSKernAttributeName] = _mTextKern == 0 ? nil : @(_mTextKern);
    
    // 文字连体
    attributes[NSLigatureAttributeName] = _mTextLigature == 1 ? nil : @(_mTextLigature);
    
    // 膨胀 文字横向宽窄
    attributes[NSExpansionAttributeName] = _mTextExpansion == 0 ? nil : @(_mTextExpansion);
    
    // 倾斜 文字倾斜度
    attributes[NSObliquenessAttributeName] = _mTextObliqueness == 0 ? nil : @(_mTextObliqueness);
    
    // 下划线
    if (_mTextUnderlineStyle != NSUnderlineStyleNone && _mTextUnderlineColor != nil) {
        attributes[NSUnderlineColorAttributeName] = _mTextUnderlineColor;
        attributes[NSUnderlineStyleAttributeName] = @(_mTextUnderlineStyle);
    }
    
    // 删除线
    if (_mTextStrikethroughStyle != 0 && _mTextStrikethroughColor != nil) {
        attributes[NSStrikethroughColorAttributeName] = _mTextStrikethroughColor;
        attributes[NSStrikethroughStyleAttributeName] = @(_mTextStrikethroughStyle);
    }
    
    // 描边线
    if (_mTextStrokeWidth > 0 && _mTextStrokeColor != nil) {
        attributes[NSStrokeColorAttributeName] = _mTextStrokeColor;
        attributes[NSStrokeWidthAttributeName] = @(_mTextStrokeWidth);
    }
    
    
    // 用属性制作富文本
    NSAttributedString *text = [[NSAttributedString alloc] initWithString:_mText attributes:attributes];
    if (_mAttr == nil) {
        _mAttr = text.mutableCopy;
    } else {
        [_mAttr appendAttributedString:text];
    }
    [self resetAttributeds];
}

- (NSAttributedString *)attributedString {
    [self createAttributedString];
    return [_mAttr copy];
}

#pragma mark -
#pragma mark 附加文字或元素
- (RICH_TEXT_IMG_RECT)imageAndBounds {
    [self createAttributedString];
    _mText = nil;
    return ^(UIImage *image, CGRect bounds) {
        NSTextAttachment *attachment = [[NSTextAttachment alloc] init];
        attachment.image = image;
        attachment.bounds = bounds;
        [_mAttr appendAttributedString:[NSAttributedString attributedStringWithAttachment:attachment]];
        return self;
    };
}
- (RICH_TEXT_IMG)image {
    [self createAttributedString];
    _mText = nil;
    return ^(UIImage *image) {
        NSTextAttachment *attachment = [NSTextAttachment new];
        attachment.image = image;
        [_mAttr appendAttributedString:[NSAttributedString attributedStringWithAttachment:attachment]];
        return self;
    };
}

- (RICH_TEXT_ATTACHMENT)attachment {
    [self createAttributedString];
    return ^(NSTextAttachment *attachment) {
        [_mAttr appendAttributedString:[NSAttributedString attributedStringWithAttachment:attachment]];
        return self;
    };
}

- (RICH_TEXT_STRING)text {
    [self createAttributedString];
    return ^(NSString *text) {
        _mText = text;
        return self;
    };
}

- (RICH_TEXT_FORMAT)format {
    return ^(NSString *format, ...) {
        va_list args;
        va_start(args, format);
        NSString *result = [[NSString alloc] initWithFormat:format arguments:args];
        va_end(args);
        return self.text(result);
    };
}

#pragma mark 字体与颜色
- (RICH_TEXT_FONT)font {
    return ^(UIFont *font) {
        _mTextFont = font;
        return self;
    };
}

- (RICH_TEXT_COLOR)textColor {
    return ^(UIColor *color) {
        _mTextColor = color;
        return self;
    };
}

- (RICH_TEXT_COLOR)backgroundColor {
    return ^(UIColor *color) {
        _mBackColor = color;
        return self;
    };
}

#pragma mark 文字位置与角度
- (RICH_TEXT_INT)ligature {
    return ^(NSInteger value) {
        _mTextLigature = value;
        return self;
    };
}
- (RICH_TEXT_FLOAT)kern {
    return ^(CGFloat value) {
        _mTextKern = value;
        return self;
    };
}
- (RICH_TEXT_FLOAT)expansion {
    return ^(CGFloat value) {
        _mTextExpansion = value;
        return self;
    };
}
- (RICH_TEXT_FLOAT)obliqueness {
    return ^(CGFloat value) {
        _mTextObliqueness = value;
        return self;
    };
}
- (RICH_TEXT_FLOAT)baselineOffset {
    return ^(CGFloat value) {
        _mTextBaselineOffset = value;
        return self;
    };
}

#pragma mark 阴影 & 超链接
- (RICH_TEXT_STRING)link {
    return ^(NSString * text) {
        _mTextLink = text;
        return self;
    };
}
- (RICH_TEXT_SHADOW)shadow {
    return ^(NSShadow *shadow) {
        _mTextShadow = shadow;
        return self;
    };
}

#pragma mark 段落样式
- (RICH_TEXT_PARAGRAPH)paragraph {
    return ^(NSParagraphStyle *paragraph) {
        _mParagraphStyle = paragraph;
        return self;
    };
}

- (RICH_TEXT_FLOAT)lineSpacing {
    return ^(CGFloat value) {
        NSMutableParagraphStyle *style = _mParagraphStyle.mutableCopy ?: [NSMutableParagraphStyle defaultParagraphStyle].mutableCopy;
        style.lineSpacing = value;
        _mParagraphStyle = style;
        return self;
    };
}
- (RICH_TEXT_FLOAT)paragraphSpacing {
    return ^(CGFloat value) {
        NSMutableParagraphStyle *style = _mParagraphStyle.mutableCopy ?: [NSMutableParagraphStyle defaultParagraphStyle].mutableCopy;
        style.paragraphSpacing = value;
        _mParagraphStyle = style;
        return self;
    };
}
- (RICH_TEXT_ALIGNMENT)alignment {
    return ^(NSTextAlignment alignment) {
        NSMutableParagraphStyle *style = _mParagraphStyle.mutableCopy ?: [NSMutableParagraphStyle defaultParagraphStyle].mutableCopy;
        style.alignment = alignment;
        _mParagraphStyle = style;
        return self;
    };
}
- (RICH_TEXT_FLOAT)firstLineHeadIndent {
    return ^(CGFloat value) {
        NSMutableParagraphStyle *style = _mParagraphStyle.mutableCopy ?: [NSMutableParagraphStyle defaultParagraphStyle].mutableCopy;
        style.firstLineHeadIndent = value;
        _mParagraphStyle = style;
        return self;
    };
}
- (RICH_TEXT_FLOAT)headIndent {
    return ^(CGFloat value) {
        NSMutableParagraphStyle *style = _mParagraphStyle.mutableCopy ?: [NSMutableParagraphStyle defaultParagraphStyle].mutableCopy;
        style.headIndent = value;
        _mParagraphStyle = style;
        return self;
    };
}
- (RICH_TEXT_FLOAT)tailIndent {
    return ^(CGFloat value) {
        NSMutableParagraphStyle *style = _mParagraphStyle.mutableCopy ?: [NSMutableParagraphStyle defaultParagraphStyle].mutableCopy;
        style.tailIndent = value;
        _mParagraphStyle = style;
        return self;
    };
}
- (RICH_TEXT_BREAKMODE)lineBreakMode {
    return ^(NSLineBreakMode breakMode) {
        NSMutableParagraphStyle *style = _mParagraphStyle.mutableCopy ?: [NSMutableParagraphStyle defaultParagraphStyle].mutableCopy;
        style.lineBreakMode = breakMode;
        _mParagraphStyle = style;
        return self;
    };
}
- (RICH_TEXT_FLOAT)minimumLineHeight {
    return ^(CGFloat value) {
        NSMutableParagraphStyle *style = _mParagraphStyle.mutableCopy ?: [NSMutableParagraphStyle defaultParagraphStyle].mutableCopy;
        style.minimumLineHeight = value;
        _mParagraphStyle = style;
        return self;
    };
}
- (RICH_TEXT_FLOAT)maximumLineHeight {
    return ^(CGFloat value) {
        NSMutableParagraphStyle *style = _mParagraphStyle.mutableCopy ?: [NSMutableParagraphStyle defaultParagraphStyle].mutableCopy;
        style.maximumLineHeight = value;
        _mParagraphStyle = style;
        return self;
    };
}
- (RICH_TEXT_DIRECTION)baseWritingDirection {
    return ^(NSWritingDirection direction) {
        NSMutableParagraphStyle *style = _mParagraphStyle.mutableCopy ?: [NSMutableParagraphStyle defaultParagraphStyle].mutableCopy;
        style.baseWritingDirection = direction;
        _mParagraphStyle = style;
        return self;
    };
}
- (RICH_TEXT_FLOAT)lineHeightMultiple {
    return ^(CGFloat value) {
        NSMutableParagraphStyle *style = _mParagraphStyle.mutableCopy ?: [NSMutableParagraphStyle defaultParagraphStyle].mutableCopy;
        style.lineHeightMultiple = value;
        _mParagraphStyle = style;
        return self;
    };
}
- (RICH_TEXT_FLOAT)paragraphSpacingBefore {
    return ^(CGFloat value) {
        NSMutableParagraphStyle *style = _mParagraphStyle.mutableCopy ?: [NSMutableParagraphStyle defaultParagraphStyle].mutableCopy;
        style.paragraphSpacingBefore = value;
        _mParagraphStyle = style;
        return self;
    };
}
- (RICH_TEXT_FLOAT)hyphenationFactor {
    return ^(CGFloat value) {
        NSMutableParagraphStyle *style = _mParagraphStyle.mutableCopy ?: [NSMutableParagraphStyle defaultParagraphStyle].mutableCopy;
        style.hyphenationFactor = value;
        _mParagraphStyle = style;
        return self;
    };
}
- (RICH_TEXT_FLOAT)defaultTabInterval {
    return ^(CGFloat value) {
        NSMutableParagraphStyle *style = _mParagraphStyle.mutableCopy ?: [NSMutableParagraphStyle defaultParagraphStyle].mutableCopy;
        style.defaultTabInterval = value;
        _mParagraphStyle = style;
        return self;
    };
}

#pragma mark 线条相关
- (RICH_TEXT_LINE)underline {
    return ^(NSNumber *value, UIColor *color) {
        _mTextUnderlineStyle = value.integerValue;
        _mTextUnderlineColor = color;
        return self;
    };
}

- (RICH_TEXT_LINE)stroke {
    return ^(NSNumber *value, UIColor *color) {
        _mTextStrokeWidth = value.doubleValue;
        _mTextStrokeColor = color;
        return self;
    };
}

- (RICH_TEXT_LINE)strikethrough {
    return ^(NSNumber *value, UIColor *color) {
        _mTextStrikethroughStyle = value.integerValue;
        _mTextStrikethroughColor = color;
        return self;
    };
}

#pragma mark 方向 & 特效
- (RICH_TEXT_DIRECTION)direction {
    return ^(NSInteger value) {
        _mTextDirection = value;
        return self;
    };
}

-(RichTextMaker *)vertical {
    _mTextDirection = 1;
    return self;
}

- (RichTextMaker *)effectLetterpress {
    _mTextEffect = NSTextEffectLetterpressStyle;
    return self;
}

@end
